package com.dragon.modules.yuegou.model.rbac;

import com.dragon.modules.yuegou.web.LinkedTree;
import com.dragon.modules.yuegou.web.Tree;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * 资源
 * 
 * @author liuwu
 *
 */
public class RbacResource {

	@ApiModelProperty("ID")
	protected final String id;

	@Nullable
	@ApiModelProperty("父ID")
	protected final String parentId;

	@ApiModelProperty("名称")
	protected final String name;

	@ApiModelProperty("路径")
	protected final String path;
	
	@ApiModelProperty("系统角色集合")
	protected final Set<String> roles;
	
	@ApiModelProperty("路径")
	protected final Integer sortNo;

	@JsonCreator
	public RbacResource(@JsonProperty("id") String id, @JsonProperty("parentId") String parentId,
			@JsonProperty("name") String name, @JsonProperty("path") String path,
			@JsonProperty("roles") Set<String> roles,@JsonProperty("sortNo") Integer sortNo) {
		super();
		this.id = id;
		this.parentId = parentId;
		this.name = name;
		this.path = path;
		this.roles = roles != null ? roles : new HashSet<>();
		this.sortNo = sortNo;
	}
	
	public RbacResource(RbacResource res) {
		super();
		this.id = res.getId();
		this.parentId = res.getParentId();
		this.name = res.getName();
		this.path = res.getPath();
		this.roles = new HashSet<>(res.roles);
		this.sortNo = res.getSortNo();
	}

	public static RbacResource newInstance(String id) {
		return new RbacResource(id, null, null, null, null,null);
	}

	public String getId() {
		return id;
	}

	public String getParentId() {
		return parentId;
	}

	public String getName() {
		return name;
	}

	public String getPath() {
		return path;
	}

	public Set<String> getRoles() {
		return roles;
	}

	public Integer getSortNo() {
		return sortNo;
	}

	@Override
	public String toString() {
		return String.format("%s(%s)", name, path);
	}

	@Override
	public int hashCode() {
		return Objects.hash(id);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		RbacResource other = (RbacResource) obj;
		return Objects.equals(id, other.id);
	}

	@JsonIgnore
	public boolean isRoot() {
		return parentId == null || "0".equals(parentId);
	}

	/**
	 * 构造资源树
	 * 
	 * @param coll
	 * @return 资源树
	 */
	public static <T extends RbacResource> Tree<T> buildTree(Collection<T> coll) {
		return LinkedTree.build(coll, RbacResource::isRoot, (e, r) -> r.getId().equals(e.getParentId()),
				(o1, o2) -> o1.getName().compareTo(o2.getName()));
	}

	
	/**
	 * 构造资源树
	 * 
	 * @param coll
	 * @return 资源树
	 */
	public static <T extends RbacResource> Tree<T> buildTreeSortById(Collection<T> coll) {
		return LinkedTree.build(coll, RbacResource::isRoot, (e, r) -> r.getId().equals(e.getParentId()),
				(o1, o2) -> o1.getId().compareTo(o2.getId()));
	}
}
